#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/cdev.h>

#define LED1 74
#define LED_ON	0x1001
#define LED_OFF	0x1000

MODULE_LICENSE("GPL");

static dev_t devt;
static struct cdev* ledCdev;

int led_open(struct inode *inode, struct file *filePtr)
{
    printk("leddev is open\n");
    return 0;
}

long led_ioctl(struct file * filePtr, unsigned int request, unsigned long arg)
{
    if(request == LED_ON){
        gpio_set_value(LED1,1);
    }else if(request == LED_OFF){
        gpio_set_value(LED1,0);
    }else{
        printk("invalid argment\n");
        return -EINVAL;
    }
    return 0;
}

struct file_operations ledFops = 
{
    .owner = THIS_MODULE,
    .open = led_open,
    .unlocked_ioctl = led_ioctl
};

static int __init led_drv_init(void)
{
    alloc_chrdev_region(&devt, 0, 1, "led1");
    ledCdev = cdev_alloc();
    cdev_init(ledCdev,&ledFops);
    cdev_add(ledCdev,devt,1);

    if(gpio_request(LED1,"led1"))
    {
        printk("gpio_request is failed\n");
        return -EINVAL;
    }

    gpio_direction_output(LED1,0);
    return 0;
}

static void __exit led_drv_exit(void)
{
    gpio_free(LED1);
    cdev_del(ledCdev);
    unregister_chrdev_region(devt,1);
}

module_init(led_drv_init);
module_exit(led_drv_exit);